home *** CD-ROM | disk | FTP | other *** search
Wrap
/** Make_Get_and_Set_Functions.bsh - a BeanShell macro for the jEdit text editor that creates simple get() and set() methods for the variables on selected lines. Copyright (C) 2004 Thomas Galvin - software@thomas-galvin.com based on Make_Get_and_Set_Methods.bsh by John Gellene This macro will work on multiple selected lines; for instance, selecting <code> public int foo; public int bar; </code> and running the macro will produce get and set functions for both variables, along with comments. This macro produces c-style functions, unless the buffer is in java mode. Modifications by Dale Anson, Dec 2008: 1. Allows variable declarations to have an initial assignment, like <code> public int foo = 1; public int bar = 2; </code> 2. Allows multiple variables on same line, like <code> public int foo, bar; </code> 3. Use line separator as set in buffer properties rather than always using \n. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ // Localization final static String DONE = jEdit.getProperty("macro.rs.MakeGetAndSetMethods.GenerateCode.label", "Generate Code"); final static String CANCEL = jEdit.getProperty("common.cancel"); final static String CreateGetMethodsLabel = jEdit.getProperty("macro.rs.MakeGetAndSetMethods.CreateGetMethods.label", "Create Get Methods"); final static String CreateSetMethodsLabel = jEdit.getProperty("macro.rs.MakeGetAndSetMethods.CreateSetMethods.label", "Create Set Methods"); final static String CreateGetandSetMethodsLabel = jEdit.getProperty("macro.rs.MakeGetAndSetMethods.CreateGetandSetMethods.label", "Create Get and Set Methods"); //Process boolean JAVA_MODE = buffer.getMode().getName().equals( "java" ); // use line separator from current buffer String LS = buffer.getStringProperty( "lineSeparator" ); if (LS == null) { // otherwise, use default line separator LS = jEdit.getProperty("buffer.lineSeparator"); } boolean createGetMethods = true; boolean createSetMethods = true; void setCaret( int selectionStart, int selectionEnd ) { textArea.setCaretPosition( selectionStart ); textArea.moveCaretPosition( selectionEnd ); } String getClassName() { int selectionStart; int selectionEnd; if(textArea.getSelection().length != 0){ // if there are selections exists selectionStart = textArea.getSelection(0).getStart(); selectionEnd = textArea.getSelection(0).getEnd(); } else { // if no selection selectionStart = textArea.getCaretPosition(); selectionEnd = textArea.getCaretPosition(); } String text = textArea.getText(); int index = text.lastIndexOf( "class", selectionStart ); if ( index != -1 ) { textArea.setCaretPosition( index ); int lineNumber = textArea.getCaretLine(); int lineEnd = textArea.getLineEndOffset( lineNumber ); String lineText = text.substring( index, lineEnd ); StringTokenizer tokenizer = new StringTokenizer( lineText ); tokenizer.nextToken(); //eat "class" if ( tokenizer.hasMoreTokens() ) { setCaret( selectionStart, selectionEnd ); return tokenizer.nextToken(); } } setCaret( selectionStart, selectionEnd ); String fileClassName = buffer.getName(); int index = fileClassName.lastIndexOf( '.' ); if ( index != -1 ) { fileClassName = fileClassName.substring( 0, index ); if ( fileClassName.toLowerCase().indexOf( "untitled" ) == -1 ) { return fileClassName; } } return ""; } String createJavaGetMethod( String type, String variableName ) { String uppperVariable = Character.toUpperCase( variableName.charAt( 0 ) ) + variableName.substring( 1, variableName.length() ); String result = "\t/**" + LS + "\t * Returns the value of " + variableName + "." + LS + "\t */" + LS + "\tpublic " + type + " get" + uppperVariable + "() {" + LS + "\t\treturn " + variableName + ";" + LS + "\t}" + LS; return result; } String createJavaSetMethod( String type, String variableName ) { String uppperVariable = Character.toUpperCase( variableName.charAt( 0 ) ) + variableName.substring( 1, variableName.length() ); String result = "\t/**" + LS + "\t * Sets the value of " + variableName + "." + LS + "\t * @param " + variableName + " The value to assign " + variableName + "." + LS + "\t */" + LS + "\tpublic void set" + uppperVariable + "(" + type + " " + variableName + ") {" + LS + "\t\tthis." + variableName + " = " + variableName + ";" + LS + "\t}" + LS; return result; } String createCppGetMethod( String className, String type, String variableName ) { String scopeIndicator = ""; if ( className != null && className.compareTo( "" ) != 0 ) { scopeIndicator = className + "::"; } if (type == null) { type = ""; } String uppperVariable = Character.toUpperCase( variableName.charAt( 0 ) ) + variableName.substring( 1, variableName.length() ); String result = "/*" + LS + "function: get" + uppperVariable + "()" + LS + "Returns the value of " + variableName + "." + LS + "*/" + LS + type + (type.length() > 0 ? " " : "") + scopeIndicator + "get" + uppperVariable + "()" + "" + LS + "{" + "" + LS + " return " + variableName + ";" + "" + LS + "}" + LS; return result; } String createCppSetMethod( String className, String type, String variableName ) { String scopeIndicator = ""; if ( className != null && className.compareTo( "" ) != 0 ) { scopeIndicator = className + "::"; } String uppperVariable = Character.toUpperCase( variableName.charAt( 0 ) ) + variableName.substring( 1, variableName.length() ); String setVariable = variableName + "Value"; String result = "/*" + LS + "function: set" + uppperVariable + "()" + LS + "Sets the value of " + variableName + "." + LS + "Input: " + setVariable + " The value to assign " + variableName + "." + LS + "*/" + LS + "void " + scopeIndicator + "set" + uppperVariable + "(const " + type + "& " + setVariable + ")" + LS + "{" + "" + LS + " " + variableName + " = " + setVariable + ";" + "" + LS + "}" + LS; return result; } void parseSelection() { // offsets from start of buffer int selectionStart; int selectionEnd; if (textArea.getSelection().length() == 0) { // no selection, use current line selectionStart = textArea.getLineStartOffset(textArea.getCaretLine()); selectionEnd = textArea.getLineEndOffset(textArea.getCaretLine()); } else { selectionStart = textArea.getSelection(0).getStart(); selectionEnd = textArea.getSelection(0).getEnd(); } StringBuffer code = new StringBuffer(); String className = getClassName(); // remove comments and blank lines ArrayList lines = stripComments(buffer, selectionStart, selectionEnd); if (lines.size() == 0) { return; } // parse each line for variable declaration. Lines are already trimmed and // have all comments removed. for (int i = 0; i < lines.size(); i++) { String lineText = lines.get(i); // combine lines up to next semi-colon into a single line while(!lineText.endsWith(";") && i < lines.size()) { lineText += lines.get(++i); } // ensure line contains at least two words, that is, a type // and a variable name at minimum. This is a fairly lame check in that // "public int" would qualify, but it does mean that I don't have to // do so much bounds checking below. if (!lineText.matches("\\S+\\s+[_A-Za-z0-9$]+.*?")) { continue; } // remove semi-colon if ( lineText.endsWith( ";" ) ) { lineText = lineText.substring( 0, lineText.length() - 1 ); } lineText = lineText.trim(); if ( lineText.length() == 0 ) { continue; } // list to hold variable names ArrayList variables = new ArrayList(); // the variable type String type = ""; // could have declaration like "int x, y = 6;", which is why there // needs to be an array for the variable names if ( lineText.indexOf( "," ) > 0 ) { int comma = lineText.indexOf(","); String front = lineText.substring(0, comma); // everything before the first comma if (front.indexOf("=") > 0) { front = front.substring(0, front.indexOf("=")); // drop the initial value } front = front.trim(); String[] fronts = front.split("\\s+"); variables.add(fronts[fronts.length - 1]); // last item in array is variable name type = fronts[fronts.length - 2]; // next to last item is type String back = lineText.substring(comma + 1); // everything after the first comma String[] backs = back.split(","); for (back : backs) { back = back.trim(); String[] parts = back.split("\\s+"); // could have initializer with spaces String var = extractVar(parts[0]); // could have i=0, ie, no spaces variables.add(var); } } else { // just one variable declared, may be initialized if (lineText.indexOf("=") > 0) { lineText = lineText.substring(0, lineText.indexOf("=")); // drop the intial value } lineText = lineText.trim(); String[] parts = lineText.split("\\s+"); variables.add(extractVar(parts[parts.length - 1])); // last item in array is variable name type = parts[parts.length - 2]; // next to last item is type } type = type.trim(); if (variables.size() == 0) { continue; } code.append( LS ); // create the get and set methods for each variable for ( String variable : variables ) { if ( createGetMethods ) { String tmp = JAVA_MODE ? createJavaGetMethod( type, variable ) : createCppGetMethod( className, type, variable ); if ( tmp != null && tmp.length() > 0 ) { code.append( tmp ).append( LS ); } } if ( createSetMethods && lineText.indexOf( "final " ) == -1 && lineText.indexOf( "const " ) == -1 ) { String tmp = JAVA_MODE ? createJavaSetMethod( type, variable ) : createCppSetMethod( className, type, variable ); if ( tmp != null && tmp.compareTo( "" ) != 0 ) { code.append( LS ).append( tmp ).append( LS ); } } } } String toInsert = code.toString(); if (toInsert.trim().length() == 0) { return; } // move to the end of the selected text textArea.setCaretPosition( selectionEnd ); // insert get/set methods textArea.setSelectedText( toInsert ); // select the inserted code and indent it textArea.setCaretPosition( selectionEnd ); textArea.moveCaretPosition( selectionEnd + code.length(), true ); textArea.indentSelectedLines(); } import org.gjt.sp.jedit.syntax.*; // Given the buffer and start and end of the selection, remove comments and // blank lines, then return a list of the remaining lines. The list contains // the trimmed line text. ArrayList stripComments( Buffer buffer, int startOffset, int endOffset ) { int firstLine = buffer.getLineOfOffset(startOffset); // the last line may not actually have anything selected, just the caret // happens to be at the start of the line or include part of the whitespace // at the start of the line. In this case, don't include the last line. int lastLine = buffer.getLineOfOffset(endOffset); String lastLineText = buffer.getText(buffer.getLineStartOffset(lastLine), endOffset - buffer.getLineStartOffset(lastLine)); if (lastLineText.trim().length() == 0) { --lastLine; } ArrayList lines = new ArrayList(); DefaultTokenHandler tokenHandler = new DefaultTokenHandler(); StringBuilder lineBuffer = new StringBuilder(); for ( int lineNum = firstLine; lineNum <= lastLine; lineNum++ ) { int lineStart = buffer.getLineStartOffset(lineNum); lineBuffer.delete(0, lineBuffer.length()); tokenHandler.init(); buffer.markTokens( lineNum, tokenHandler ); Token token = tokenHandler.getTokens(); // skip comments while(token.id != Token.END) { if (token.id < Token.COMMENT1 || token.id > Token.COMMENT4) { lineBuffer.append(buffer.getText(lineStart + token.offset, token.length)); } token = token.next; } String line = lineBuffer.toString().trim(); // skip blank lines if (line.length() > 0) { lines.add(line.trim()); } } return lines; } boolean isWhitespace(Token token) { String text = buffer.getText(token.offset, token.length); return text.trim().length() == 0; } // given something line "a = 6", returns just the "a". String extractVar(String var) { if (var == null) { return ""; } var = var.trim(); if (var.indexOf("=") > 0) { var = var.substring(0, var.indexOf("=")).trim(); } return var; } void displayPrompt() { JCheckBox getCheckbox = new JCheckBox( CreateGetMethodsLabel, true ); JCheckBox setCheckbox = new JCheckBox( CreateSetMethodsLabel, true ); JPanel checkBoxPanel = new JPanel(new BorderLayout()); checkBoxPanel.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6)); checkBoxPanel.add( getCheckbox, BorderLayout.NORTH ); checkBoxPanel.add( setCheckbox, BorderLayout.SOUTH ); JButton createButton = new JButton( DONE ); JButton cancelButton = new JButton( CANCEL ); JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 6, 0)); buttonPanel.setBorder(BorderFactory.createEmptyBorder(11, 11, 11, 11)); buttonPanel.add( createButton, BorderLayout.WEST ); buttonPanel.add( cancelButton, BorderLayout.EAST ); JPanel mainPanel = new JPanel(); mainPanel.setLayout( new BorderLayout() ); mainPanel.add( checkBoxPanel, BorderLayout.NORTH ); mainPanel.add( buttonPanel, BorderLayout.SOUTH ); JDialog dialog = new JDialog( view, CreateGetandSetMethodsLabel, false ); dialog.setContentPane( mainPanel ); actionPerformed( ActionEvent e ) { if ( e.getSource() == createButton ) { createGetMethods = getCheckbox.isSelected(); createSetMethods = setCheckbox.isSelected(); parseSelection(); } this.dialog.dispose(); return ; } createButton.addActionListener( this ); cancelButton.addActionListener( this ); dialog.pack(); dialog.setLocationRelativeTo( view ); dialog.setDefaultCloseOperation( JDialog.DISPOSE_ON_CLOSE ); dialog.setVisible( true ); createButton.requestFocus(); } final static String NotEditableMessage = jEdit.getProperty("macro.rs.general.ErrorNotEditableDialog.message", "Buffer is not editable"); if ( buffer.isReadOnly() ) Macros.error( view, NotEditableMessage ); else displayPrompt();